package com.zefor.warns;

import com.zefor.utils.CacheUtil;
import kd.bos.cache.LocalMemoryCache;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.earlywarn.EarlyWarnContext;
import kd.bos.entity.earlywarn.warn.plugin.IEarlyWarnWriteOut;
import kd.bos.kdtx.common.exception.KdtxException;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.drp.mdr.common.util.ObjectUtil;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;


/**
 * 自定义数据源写出
 */
public class EnvWarnWriteOutPlugin implements IEarlyWarnWriteOut {
    //获取缓存操作
    private final LocalMemoryCache localCache = CacheUtil.getCache();

    @Override
    public void writeOut(DynamicObjectCollection dynamicObjectCollection, EarlyWarnContext earlyWarnContext) {
        //查询环境预警标准值
        DynamicObject[] warnStandard = BusinessDataServiceHelper.load(
                "n716_warnstandard",
                "n716_mulilangtextfield, n716_decimalfield, n716_decimalfield1,n716_combofield",
                new QFilter("n716_combofield", QCP.in, new ArrayList<String>() {{
                    add("温度");
                    add("湿度");
                    add("二氧化碳");
                    add("光照量");
                }}).toArray());
        Map<String, BigDecimal[]> standard = queryStandard(warnStandard, "温度", "湿度", "二氧化碳", "光照量");
        //判断为空
        if (ObjectUtil.isEmpty(standard)) throw new KdtxException("查询环境预警值参数异常");

        //过滤后的条件
        for (int i = 0; i < dynamicObjectCollection.size(); i++) {
            //获取今天的所有信息
            DynamicObjectCollection entryentity = dynamicObjectCollection.get(i).getDynamicObjectCollection("n716_entryentity");
            //四个预警信息,如果四条信息都在范围内,那么就直接删除
            HashSet<String> errMses = new HashSet<>();
            for (int j = 0; j < entryentity.size(); j++) {
                //拿出分页的每一条信息
                Map<String, BigDecimal> item = queryCorralEnvByEnvObj(entryentity.get(j));
                if (ObjectUtil.isEmpty(item)) {
                    throw new KdtxException("未获取到当前栏舍用环境信息");
                }
                for (String s : standard.keySet()) {
                    int flag = getStatus(item, standard, s);
                    if (flag == 1) {
                        //设置预警信息
                        errMses.add(s + "小于标准预警值");
                    }else if(flag == 2) {
                        errMses.add(s + "大于标准预警值");
                    }
                }
                //如果预警信息为空那么删除该条信息
                if (errMses.isEmpty()) {
                    entryentity.remove(entryentity.get(j));
                    j--;
                }
            }
            //如果所有项都不符合预警条件
            if (entryentity.size() == 0) {
                //那么把该项从中移除
                dynamicObjectCollection.remove(dynamicObjectCollection.get(i));
                i--;
            }else {
                //如果存在预警信息那么直接存储在缓存
                localCache.put(dynamicObjectCollection.get(i).getPkValue() + "warnMses", errMses);
            }
        }
        System.out.println("数据写入执行");
    }

    /*
     * 判断当前预警状态 0在预警范围内,1小于预警范围,2大于预警范围
     * @param 当前值
     * @param 当前预警值的范围
     * @param 判断条件
     * */
    private int getStatus(Map<String, BigDecimal> num, Map<String, BigDecimal[]> range, String args) {
        double minNum = range.get(args)[0].doubleValue();
        double maxNum = range.get(args)[1].doubleValue();
        double item = num.get(args).doubleValue();
        if (item >= minNum && item <= maxNum) {
            //未达触发预警条件,移除该项
            return 0;
        } else if (item < minNum) {
            //未触发预警条件,设置通知消息
            return 1;
        } else {
            return 2;
        }
    }


    /*
     * 将当前对象转换为map对象
     * @param 转换对象
     * @return 当前的分页的记录值
     * */
    private Map<String, BigDecimal> queryCorralEnvByEnvObj(DynamicObject dynamicObject) {
        HashMap<String, BigDecimal> result = new HashMap<>();
        result.put("温度", dynamicObject.getBigDecimal("n716_decimalfield"));
        result.put("湿度", dynamicObject.getBigDecimal("n716_decimalfield1"));
        result.put("二氧化碳", dynamicObject.getBigDecimal("n716_integerfield"));
        result.put("光照量", dynamicObject.getBigDecimal("n716_integerfield1"));
        return result;
    }


    /*
     * 查找用环境的预警标准的最大最小值
     * @param 预警标准对象数组
     * @param 需要获取数据的名称数组
     * @return 返回最大值最小值映射
     * */
    private Map<String, BigDecimal[]> queryStandard(DynamicObject[] warnStandard, String... typeName) {
        HashMap<String, BigDecimal[]> result = new HashMap<>();
        for (String name : typeName) {
            for (DynamicObject warn : warnStandard) {
                //宽松判断
                if (warn.getString("n716_combofield").contains(name)) {
                    BigDecimal[] bigDecimals = new BigDecimal[2];
                    bigDecimals[0] = warn.getBigDecimal("n716_decimalfield");
                    bigDecimals[1] = warn.getBigDecimal("n716_decimalfield1");
                    result.put(name, bigDecimals);
                    break;
                }
            }
        }
        return result;
    }
}
